package model;

/**
 *
 * @author Dustin
 */
public class Game {
    private int seatIndex;
    private int currentPlayerIndex;
    private boolean locked;
    private boolean dealing;
    private Table table;
    private Player[] players = new Player[Table.TABLE_SIZE];

    public Game(String aName) {
        table = new Table(aName);
    }

    public int getAmountOfPlayers() {
        return seatIndex;
    }

    public boolean isLocked() {
        return locked;
    }

    public boolean isDealing() {
        return dealing;
    }

    public Player getCurrentPlayer() {
        return players[currentPlayerIndex];
    }

    public int getCurrentPlayerIndex() {
        return currentPlayerIndex;
    }

    public int getAmountOfLosers() {
        System.out.println("Calculating losers");
        int losers = 0;
        for(Player p: players) {
            if(p.getPoints() == 0) {
                losers++;
            }
        }
        return losers;
    }

    public Player getPlayer(int index) {
        return players[index];
    }

    public Player[] getPlayers() {
        return players;
    }

    public Table getTable() {
        return table;
    }

    public void setNextPlayer() {
        int startIndex = currentPlayerIndex;
        currentPlayerIndex = ++currentPlayerIndex % Table.TABLE_SIZE;
        while(players[currentPlayerIndex].getPoints() == 0 && startIndex != currentPlayerIndex) {
            currentPlayerIndex = ++currentPlayerIndex % Table.TABLE_SIZE;
        }
        System.out.println("Next player is " + players[currentPlayerIndex].getName());
        
        if(players[currentPlayerIndex].isLastTurn()) {
            updateScores();
            if(getAmountOfLosers() == 3) {
                System.out.println("Speler " + players[currentPlayerIndex].getName() + " is de winnaar");
            } else {
                deal();
            }
        }
    }

    public void setLocked(boolean value) {
        locked = value;
    }

    public void setIsDealing(boolean value) {
        dealing = value;
    }

    public void setPlayer(Player aPlayer) {
        if(seatIndex < Table.TABLE_SIZE) {
            aPlayer.setPoints(1);
            players[seatIndex++] = aPlayer;
        }
    }

    public void computerPlayerTurn() {
        if(players[currentPlayerIndex] instanceof ComputerPlayer) {
            ((ComputerPlayer) players[currentPlayerIndex]).doTurn(this);
            setNextPlayer();
        }
    }

    public void deal() {
        System.out.println("Dealing...");
        dealing = true;
        for(Player p : players) {
            if(p.getPoints() > 0) {
                p.setLastTurn(false);
            } else {
                p.resetHand();
            }
        }
        table.getDeck().reset();
        table.getDeck().shuffle();

        int index = currentPlayerIndex;
        for(int i = 0; i < Player.HAND_SIZE; i++) {
            for(int j = 0; j < Table.TABLE_SIZE; j++) {
                if(players[index].getPoints() > 0) {
                    players[index].setCard(i, table.getDeck().pop());
                }
                index = (index == Table.TABLE_SIZE - 1 ? 0 : index + 1);
            }
            table.setCard(i, table.getDeck().pop());
        }
        
        table.setCard(Table.AMOUNT_OF_TABLE_CARDS - 1, table.getDeck().pop());
        System.out.println("Next round starting...");
    }
    
    public void updateScores() {
        Player[] tmpPlayers = new Player[players.length];
        for(int i = 0; i < players.length && players[i] != null; i++) {
            tmpPlayers[i] = players[i];
        }
        //get scores
        double[] scores = new double[tmpPlayers.length];
        for(int i = 0; i < scores.length; i++) {
            scores[i] = tmpPlayers[i].getPoints() > 0 ? PointController.determinePoints(tmpPlayers[i].getHand()) : 0.0;
            System.out.println(players[i].getName() + " " + scores[i] + " " + players[i].getHand()[0] + " " + players[i].getHand()[1] + " " + players[i].getHand()[2]);
        }
        //insertion sort scores
        for(int i = 0; i < scores.length; i++) {
            double tmpScore = scores[i];
            Player tmpPlayer = tmpPlayers[i];
            int j = i;
            for(; j > 0 && scores[j-1] > tmpScore; j--) {
                scores[j] = scores[j-1];
                tmpPlayers[j] = tmpPlayers[j-1];
            }
            scores[j] = tmpScore;
            tmpPlayers[j] = tmpPlayer;
        }
        //update scores
        double lowestScore = 0.0;
        for(int i = 0; i < scores.length && lowestScore == 0.0; i++) {
            if(scores[i] > 0.0) {
                lowestScore = scores[i];
                System.out.println("Lowest score " + lowestScore);
            }
        }
        for(int i = 0; i < tmpPlayers.length && scores[i] <= lowestScore; i++) {
            if(tmpPlayers[i].getPoints() > 0) {
                tmpPlayers[i].setPoints(tmpPlayers[i].getPoints() - 1);
                System.out.println(tmpPlayers[i].getName() + " is out!");
            }
        }
    }
}
